package dict

import (
	"sync"
)

type Dict[K comparable, V any] struct {
	sync.RWMutex
	m map[K]V
}

func New[K comparable, V any]() *Dict[K, V] {
	p := new(Dict[K, V])
	p.m = make(map[K]V)
	return p
}

func (p *Dict[K, V]) Set(key K, val V) {
	p.Lock()
	defer p.Unlock()
	p.m[key] = val
}

func (p *Dict[K, V]) Get(key K) (val V, found bool) {
	p.RLock()
	defer p.RUnlock()
	val, found = p.m[key]
	return
}

func (p *Dict[K, V]) Delete(key K) {
	p.Lock()
	defer p.Unlock()
	delete(p.m, key)
}

func (p *Dict[K, V]) Len() int {
	p.RLock()
	defer p.RUnlock()
	return len(p.m)
}

func (p *Dict[K, V]) Range(f func(K, V)) {
	p.Lock()
	defer p.Unlock()
	for key, val := range p.m {
		f(key, val)
	}
}
